﻿using UnityEngine;
using System.Collections;

public class EnemyShipFlight : MonoBehaviour {
	// Enums
	public ShipDirection direction = ShipDirection.FORWARD;
	public ShipRotation rotation = ShipRotation.FORWARD;

	public float strafeAmount;
	public float strafeSpeed;

	public float followingDistance; // How close the ship will be to target before slowing down
	public float slowFollowingSpeed; // How slow the ship will be if it gets too close
	float originalMoveSpeed; // For storing original move speed

	public float lockingDistance; // How close until the ship stops behind target when homing

	public float turnSpeed; // How fast the ship will turn
	public float moveSpeed; // How fast the ship will move


	Quaternion rotationDirection; // The rotation the ship will turn to

	public Transform forwardTransform; // Determine which direction is forward
	Vector3 targetDirection; // Current direction the ship is moving
	
	public GameObject target; // Position to home in on
	public Vector3 targetPosition;
	public int positionIndex;

	// Initialization
	void Start () {
		originalMoveSpeed = moveSpeed;
		rotationDirection = transform.rotation;
		updateDirection();
	}

	// Update the direction of the ship based on enum
	void updateDirection() {
		// Determine the target direction based on enum direction
		switch(direction) {
		case ShipDirection.LOCKED:
			rotation = ShipRotation.FORWARD;
			targetDirection = transform.position;
			targetPosition = target.transform.position;
			transform.position = target.transform.position;
			break;
		case ShipDirection.STATIONARY:
			targetDirection = transform.position;
			rotation = ShipRotation.FORWARD;
			targetPosition = transform.position;
			break;
		case ShipDirection.FORWARD:
			targetDirection = forwardTransform.position;
			break;
		case ShipDirection.RIGHT:
			targetDirection = new Vector3 (transform.position.x, transform.position.y + forwardTransform.position.x, transform.position.z);
			break;
		case ShipDirection.LEFT:
			targetDirection = new Vector3 (transform.position.x, transform.position.y - forwardTransform.position.x, transform.position.z);
			break;
		case ShipDirection.HOMING: // Go to target and stop
			if(target != null) {
				targetDirection = forwardTransform.position;
				// If ship is near target, change ship to stationary
				if(Vector3.Distance(targetPosition, transform.position) < lockingDistance) {
					direction = ShipDirection.LOCKED;
				} 
			} else {
				direction = ShipDirection.FORWARD;
			}
			break;
		case ShipDirection.FOLLOWING: // Keep following target
			if(target != null) {
				targetDirection = forwardTransform.position;
				if(Vector3.Distance(target.transform.position, transform.position) < followingDistance) {
					moveSpeed = slowFollowingSpeed;
				} else {
					moveSpeed = originalMoveSpeed;
				}
			} else {
				direction = ShipDirection.FORWARD;
			}
			break;
		default:
			targetDirection = forwardTransform.position;
			break;
		}
	}

	// Set rotation of ship based on enum
	void updateRotation() {
		// Determine rotation of ship
		switch(rotation) {
		case ShipRotation.FORWARD: // Turn forward
			rotationDirection = Quaternion.Euler (new Vector3(0f, 0f, 180f));
			break;
		case ShipRotation.RIGHT: // Turn right
			rotationDirection = Quaternion.Euler (new Vector3(0f, 0f, 90f));
			break;
		case ShipRotation.LEFT: // Turn left
			rotationDirection = Quaternion.Euler (new Vector3(0f, 0f, 270f));
			break;
		case ShipRotation.BACK: // Turn backwards
			rotationDirection = Quaternion.Euler (new Vector3(0f, 0f, 0f));
			break;
		case ShipRotation.HOMING: // Constantly rotate towards target point
			if(target != null) { // Only do this if there is a target
				targetPosition = target.transform.position; // Set target position to target that's tracking
				float angle = Vector3.Angle(Vector3.up, targetPosition - transform.position) + 90; // Set the angle
				if(transform.position.x - targetPosition.x < 0) { // If the ship flies past the target, adjust angle
					angle = -angle - 180;
				}
				// Rotate towards target
				transform.rotation = Quaternion.RotateTowards(transform.rotation, Quaternion.Euler (new Vector3(0f, 0f, angle)), turnSpeed); 
				// Set angle to forward
				if((Quaternion.Angle (transform.rotation, Quaternion.Euler (new Vector3(0f, 0f, 180f))) < 1f) && (Vector3.Distance(transform.position, targetPosition) < 0.1f)) {
					rotation = ShipRotation.FORWARD;
				}
			} else { // Reset to forward
				rotation = ShipRotation.FORWARD;
			}
			break;
		default:
			rotationDirection = Quaternion.Euler (new Vector3(0f, 0f, 180f));
			break;
		}
	}

	// Set target rotation of the ship
	public void setRotation(ShipRotation rotation) {
		this.rotation = rotation;
	}
	
	// Change direction of the ship
	public void setDirection(ShipDirection direction) {
		this.direction = direction;
	}

	// Pushes object to pool
	/*public void pushToPool() {
		// make this push to object pool
		// Destroy (gameObject);
	} */

	void Update () {
		updateDirection();
		updateRotation();
		// Rotate towards target at turnSpeed
		if(rotation == ShipRotation.HOMING) {
			// Do nothing
		} else {
			transform.rotation = Quaternion.RotateTowards (transform.rotation, rotationDirection, turnSpeed);
		}
		if(direction == ShipDirection.LOCKED) {
			// Do nothing
		} else {
			// Move forward at move speed
			transform.position = Vector3.MoveTowards (transform.position, targetDirection, Time.deltaTime * moveSpeed);
		}
	}
}
